app-chooser-online: rework of the online module
authorCosimo Cecchi <cosimoc@gnome.org>
Mon, 29 Nov 2010 17:10:06 +0000 (18:10 +0100)
committerCosimo Cecchi <cosimoc@gnome.org>
Mon, 29 Nov 2010 17:10:06 +0000 (18:10 +0100)
- the _get_default() method is now async
- the PackageKit module will return NULL in case PackageKit is not
  available in the session bus
- the dummy module doesn't exist anymore
- the dialog won't display the online button in case there's no module
  available

gtk/Makefile.am
gtk/gtkappchooserdialog.c
gtk/gtkappchoosermodule.c
gtk/gtkappchooseronline.c
gtk/gtkappchooseronline.h
gtk/gtkappchooseronlinedummy.c [deleted file]
gtk/gtkappchooseronlinedummy.h [deleted file]
gtk/gtkappchooseronlinepk.c

index 4448b475d7f94d80b91d65f90eacf148c5a52c99..ebd711817dc79113cf076a2132133fa4c0daac0c 100644 (file)
@@ -392,7 +392,6 @@ gtk_private_h_sources =             \
        gtkmountoperationprivate.h \
        gtkappchooserprivate.h  \
        gtkappchoosermodule.h   \
-       gtkappchooseronlinedummy.h \
        gtkpango.h              \
        gtkpathbar.h            \
        gtkplugprivate.h        \
@@ -543,7 +542,6 @@ gtk_base_c_sources =            \
        gtkappchooserdialog.c   \
        gtkappchoosermodule.c   \
        gtkappchooseronline.c   \
-       gtkappchooseronlinedummy.c \
        gtkorientable.c         \
        gtkpagesetup.c          \
        gtkpaned.c              \
index 4959ca9d83777cc3eeca03ec616beb0f49e7d34c..73dc7a283267a271e3a58507646681989a4d67ab 100644 (file)
@@ -60,6 +60,8 @@ struct _GtkAppChooserDialogPrivate {
   GtkWidget *app_chooser_widget;
   GtkWidget *show_more_button;
 
+  GtkAppChooserOnline *online;
+
   gboolean show_more_clicked;
 };
 
@@ -118,26 +120,53 @@ search_for_mimetype_ready_cb (GObject      *source,
     {
       gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
     }
-
-  g_object_unref (online);
 }
 
 static void
 online_button_clicked_cb (GtkButton *b,
                           gpointer   user_data)
 {
-  GtkAppChooserOnline *online;
   GtkAppChooserDialog *self = user_data;
 
-  online = gtk_app_chooser_online_get_default ();
-
-  gtk_app_chooser_online_search_for_mimetype_async (online,
+  gtk_app_chooser_online_search_for_mimetype_async (self->priv->online,
                                                     self->priv->content_type,
                                                     GTK_WINDOW (self),
                                                     search_for_mimetype_ready_cb,
                                                     self);
 }
 
+static void
+app_chooser_online_get_default_ready_cb (GObject *source,
+                                         GAsyncResult *res,
+                                         gpointer user_data)
+{
+  GtkAppChooserDialog *self = user_data;
+
+  self->priv->online = gtk_app_chooser_online_get_default_finish (source, res);
+
+  if (self->priv->online != NULL)
+    {
+      GtkWidget *action_area;
+
+      action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
+      self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
+      gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
+                          FALSE, FALSE, 0);
+      gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
+                                          TRUE);
+      g_signal_connect (self->priv->online_button, "clicked",
+                        G_CALLBACK (online_button_clicked_cb), self);
+
+      gtk_widget_show (self->priv->online_button);
+    }
+}
+
+static void
+ensure_online_button (GtkAppChooserDialog *self)
+{
+  gtk_app_chooser_online_get_default_async (app_chooser_online_get_default_ready_cb, self);
+}
+
 /* An application is valid if:
  *
  * 1) The file exists
@@ -415,7 +444,7 @@ build_dialog_ui (GtkAppChooserDialog *self)
   GtkWidget *vbox;
   GtkWidget *vbox2;
   GtkWidget *label;
-  GtkWidget *action_area, *button, *w;
+  GtkWidget *button, *w;
 
   gtk_container_set_border_width (GTK_CONTAINER (self), 5);
 
@@ -482,16 +511,6 @@ build_dialog_ui (GtkAppChooserDialog *self)
   gtk_dialog_add_action_widget (GTK_DIALOG (self),
                                 self->priv->button, GTK_RESPONSE_OK);
 
-  action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
-  self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
-  gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
-                      FALSE, FALSE, 0);
-  gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
-                                      TRUE);
-  gtk_widget_show (self->priv->online_button);
-  g_signal_connect (self->priv->online_button, "clicked",
-                    G_CALLBACK (online_button_clicked_cb), self);
-
   gtk_dialog_set_default_response (GTK_DIALOG (self),
                                    GTK_RESPONSE_OK);
 }
@@ -548,15 +567,24 @@ gtk_app_chooser_dialog_constructed (GObject *object)
 
   build_dialog_ui (self);
   set_dialog_properties (self);
+  ensure_online_button (self);
 }
 
 static void
-gtk_app_chooser_dialog_finalize (GObject *object)
+gtk_app_chooser_dialog_dispose (GObject *object)
 {
   GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
+  
+  g_clear_object (&self->priv->gfile);
+  g_clear_object (&self->priv->online);
 
-  if (self->priv->gfile)
-    g_object_unref (self->priv->gfile);
+  G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+gtk_app_chooser_dialog_finalize (GObject *object)
+{
+  GtkAppChooserDialog *self = GTK_APP_CHOOSER_DIALOG (object);
 
   g_free (self->priv->content_type);
 
@@ -624,6 +652,7 @@ gtk_app_chooser_dialog_class_init (GtkAppChooserDialogClass *klass)
   GParamSpec *pspec;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = gtk_app_chooser_dialog_dispose;
   gobject_class->finalize = gtk_app_chooser_dialog_finalize;
   gobject_class->set_property = gtk_app_chooser_dialog_set_property;
   gobject_class->get_property = gtk_app_chooser_dialog_get_property;
index bc5c0e74af3c58acdcc1da264bff3f43a0f5057c..afcf3de966b504c7b4a15c25f746eec5a2402d80 100644 (file)
@@ -28,7 +28,6 @@
 #include <gio/gio.h>
 
 #include "gtkappchooseronline.h"
-#include "gtkappchooseronlinedummy.h"
 
 #ifdef ENABLE_PACKAGEKIT
 #include "gtkappchooseronlinepk.h"
@@ -45,18 +44,16 @@ _gtk_app_chooser_module_ensure (void)
   G_LOCK (registered_ep);
 
   if (!registered_ep)
-{
-    registered_ep = TRUE;
-
-    ep = g_io_extension_point_register ("gtkappchooser-online");
-    g_io_extension_point_set_required_type (ep, GTK_TYPE_APP_CHOOSER_ONLINE);
+    {
+      registered_ep = TRUE;
 
-    _gtk_app_chooser_online_dummy_get_type ();
+      ep = g_io_extension_point_register ("gtkappchooser-online");
+      g_io_extension_point_set_required_type (ep, GTK_TYPE_APP_CHOOSER_ONLINE);
 
 #ifdef ENABLE_PACKAGEKIT
-    _gtk_app_chooser_online_pk_get_type ();
+      _gtk_app_chooser_online_pk_get_type ();
 #endif
-  }
+    }
 
   G_UNLOCK (registered_ep);
 }
index 34849d81daf01df14f39d0a15a43c201384e6410..71267ca7f59b09e559d68baec8adec518bd3fdbe 100644 (file)
 
 #include "gtkappchooseronline.h"
 
-#include "gtkappchooseronlinedummy.h"
 #include "gtkappchoosermodule.h"
+#include "gtkintl.h"
 
 #include <gio/gio.h>
 
-G_DEFINE_INTERFACE (GtkAppChooserOnline, gtk_app_chooser_online, G_TYPE_OBJECT);
+#define gtk_app_chooser_online_get_type _gtk_app_chooser_online_get_type
+static void gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface);
+G_DEFINE_INTERFACE_WITH_CODE (GtkAppChooserOnline, gtk_app_chooser_online, G_TYPE_OBJECT,
+                              g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_ASYNC_INITABLE);)
 
 static void
 gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface)
@@ -39,12 +42,24 @@ gtk_app_chooser_online_default_init (GtkAppChooserOnlineInterface *iface)
 }
 
 GtkAppChooserOnline *
-gtk_app_chooser_online_get_default (void)
+gtk_app_chooser_online_get_default_finish (GObject *source,
+                                           GAsyncResult *result)
+{
+  GtkAppChooserOnline *retval;
+
+  retval = GTK_APP_CHOOSER_ONLINE (g_async_initable_new_finish (G_ASYNC_INITABLE (source),
+                                                                result, NULL));
+
+  return retval;
+}  
+
+void
+gtk_app_chooser_online_get_default_async (GAsyncReadyCallback callback,
+                                          gpointer user_data)
 {
   GIOExtensionPoint *ep;
   GIOExtension *extension;
   GList *extensions;
-  GtkAppChooserOnline *retval;
 
   _gtk_app_chooser_module_ensure ();
 
@@ -55,14 +70,9 @@ gtk_app_chooser_online_get_default (void)
     {
       /* pick the first */
       extension = extensions->data;
-      retval = g_object_new (g_io_extension_get_type (extension), NULL);
-    }
-  else
-    {
-      retval = g_object_new (GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, NULL);
+      g_async_initable_new_async (g_io_extension_get_type (extension), G_PRIORITY_DEFAULT,
+                                  NULL, callback, user_data, NULL);
     }
-
-  return retval;
 }
 
 void
index 87ebc0893d029158f867e8b657b4451c0592b9d1..d0eca3b9e064d75d9eb41b17c156c88d6030e55d 100644 (file)
@@ -31,7 +31,7 @@
 
 G_BEGIN_DECLS
 
-#define GTK_TYPE_APP_CHOOSER_ONLINE           (gtk_app_chooser_online_get_type ())
+#define GTK_TYPE_APP_CHOOSER_ONLINE           (_gtk_app_chooser_online_get_type ())
 #define GTK_APP_CHOOSER_ONLINE(o)             (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnline))
 #define GTK_IS_APP_CHOOSER_ONLINE(o)          (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_APP_CHOOSER_ONLINE))
 #define GTK_APP_CHOOSER_ONLINE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE, GtkAppChooserOnlineInterface))
@@ -54,7 +54,13 @@ struct _GtkAppChooserOnlineInterface {
                                           GError              **error);
 };
 
-GType                 gtk_app_chooser_online_get_type                   (void) G_GNUC_CONST;
+GType                 _gtk_app_chooser_online_get_type                  (void) G_GNUC_CONST;
+
+void                  gtk_app_chooser_online_get_default_async          (GAsyncReadyCallback   callback,
+                                                                         gpointer              user_data);
+GtkAppChooserOnline * gtk_app_chooser_online_get_default_finish          (GObject             *source,
+                                                                          GAsyncResult        *result);
+
 void                  gtk_app_chooser_online_search_for_mimetype_async  (GtkAppChooserOnline  *self,
                                                                          const gchar          *content_type,
                                                                          GtkWindow            *parent,
@@ -64,6 +70,4 @@ gboolean              gtk_app_chooser_online_search_for_mimetype_finish (GtkAppC
                                                                          GAsyncResult         *res,
                                                                          GError              **error);
 
-GtkAppChooserOnline * gtk_app_chooser_online_get_default                (void);
-
 #endif /* __GTK_APP_CHOOSER_ONLINE_H__ */
diff --git a/gtk/gtkappchooseronlinedummy.c b/gtk/gtkappchooseronlinedummy.c
deleted file mode 100644 (file)
index 4ea5675..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * gtkappchooseronlinedummy.c: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#include <config.h>
-
-#include "gtkappchooseronlinedummy.h"
-
-#include "gtkintl.h"
-#include "gtkappchooseronline.h"
-
-#include <gio/gio.h>
-
-#define gtk_app_chooser_online_dummy_get_type _gtk_app_chooser_online_dummy_get_type
-static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlineDummy, gtk_app_chooser_online_dummy,
-                        G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
-                                               app_chooser_online_iface_init)
-                        g_io_extension_point_implement ("gtkappchooser-online",
-                                                        g_define_type_id,
-                                                        "dummy", 0));
-
-static void
-gtk_app_chooser_online_dummy_class_init (GtkAppChooserOnlineDummyClass *klass)
-{
-  /* do nothing */
-}
-
-static void
-gtk_app_chooser_online_dummy_init (GtkAppChooserOnlineDummy *self)
-{
-  /* do nothing */
-}
-
-static gboolean
-dummy_search_mime_finish (GtkAppChooserOnline *obj,
-                         GAsyncResult *res,
-                         GError **error)
-{
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-
-  return !g_simple_async_result_propagate_error (simple, error);
-}
-
-static void
-dummy_search_mime_async (GtkAppChooserOnline *obj,
-                        const gchar *content_type,
-                        GtkWindow *parent,
-                        GAsyncReadyCallback callback,
-                        gpointer user_data)
-{
-  g_simple_async_report_error_in_idle (G_OBJECT (obj),
-                                      callback, user_data,
-                                      G_IO_ERROR,
-                                      G_IO_ERROR_FAILED,
-                                      "%s",
-                                      _("Operation not supported"));
-}
-
-static void
-app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
-{
-  iface->search_for_mimetype_async = dummy_search_mime_async;
-  iface->search_for_mimetype_finish = dummy_search_mime_finish;
-}
diff --git a/gtk/gtkappchooseronlinedummy.h b/gtk/gtkappchooseronlinedummy.h
deleted file mode 100644 (file)
index 1253709..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * gtkappchooseronlinedummy.h: an extension point for online integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Authors: Cosimo Cecchi <ccecchi@redhat.com>
- */
-
-#ifndef __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
-#define __GTK_APP_CHOOSER_ONLINE_DUMMY_H__
-
-#include <gtk/gtkappchooseronline.h>
-#include <glib.h>
-
-#define GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY            (_gtk_app_chooser_online_dummy_get_type ())
-#define GTK_APP_CHOOSER_ONLINE_DUMMY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummy))
-#define GTK_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
-#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
-#define GTK_IS_APP_CHOOSER_ONLINE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY))
-#define GTK_APP_CHOOSER_ONLINE_DUMMY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APP_CHOOSER_ONLINE_DUMMY, GtkAppChooserOnlineDummyClass))
-
-typedef struct _GtkAppChooserOnlineDummy        GtkAppChooserOnlineDummy;
-typedef struct _GtkAppChooserOnlineDummyClass   GtkAppChooserOnlineDummyClass;
-typedef struct _GtkAppChooserOnlineDummyPrivate GtkAppChooserOnlineDummyPrivate;
-
-struct _GtkAppChooserOnlineDummy {
-  GObject parent;
-};
-
-struct _GtkAppChooserOnlineDummyClass {
-  GObjectClass parent_class;
-
-  GtkAppChooserOnlineDummy *priv;
-};
-
-GType _gtk_app_chooser_online_dummy_get_type (void);
-
-#endif /* __GTK_APP_CHOOSER_ONLINE_DUMMY_H__ */
index d307fb89be799509bd9dcdfb60ffd114eaf23346..c49854689090d3733b30205f2658366ebce84f1e 100644 (file)
 
 #define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type
 static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface);
+static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
                          G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
+                                                app_chooser_online_pk_async_initable_init)
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE,
                                                 app_chooser_online_iface_init)
                          g_io_extension_point_implement ("gtkappchooser-online",
@@ -44,20 +47,23 @@ G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk,
                                                          "packagekit", 10));
 
 struct _GtkAppChooserOnlinePkPrivate {
+  GSimpleAsyncResult *init_result;
+  guint watch_id;
+
+  GDBusProxy *proxy;
   GSimpleAsyncResult *result;
   GtkWindow *parent;
-  gchar *content_type;
 };
 
 static void
-gtk_app_chooser_online_pk_finalize (GObject *obj)
+gtk_app_chooser_online_pk_dispose (GObject *obj)
 {
   GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
 
-  g_free (self->priv->content_type);
   g_clear_object (&self->priv->result);
+  g_clear_object (&self->priv->proxy);
 
-  G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->finalize (obj);
+  G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->dispose (obj);
 }
 
 static void
@@ -65,7 +71,7 @@ gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass)
 {
   GObjectClass *oclass = G_OBJECT_CLASS (klass);
 
-  oclass->finalize = gtk_app_chooser_online_pk_finalize;
+  oclass->dispose = gtk_app_chooser_online_pk_dispose;
 
   g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate));
 }
@@ -115,40 +121,30 @@ install_mime_types_ready_cb (GObject      *source,
 }
 
 static void
-pk_proxy_appeared_cb (GObject      *source,
-                      GAsyncResult *res,
-                      gpointer      user_data)
+pk_search_mime_async (GtkAppChooserOnline *obj,
+                      const gchar         *content_type,
+                      GtkWindow           *parent,
+                      GAsyncReadyCallback  callback,
+                      gpointer             user_data)
 {
-  GtkAppChooserOnlinePk *self = user_data;
-  GDBusProxy *proxy;
-  GError *error = NULL;
+  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
   guint xid = 0;
   GdkWindow *window;
   const gchar *mime_types[2];
 
-  proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
-
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (self->priv->result, error);
-      g_error_free (error);
-
-      g_simple_async_result_complete (self->priv->result);
-
-      return;
-    }
+  self->priv->result = g_simple_async_result_new (G_OBJECT (self),
+                                                  callback, user_data,
+                                                  gtk_app_chooser_online_search_for_mimetype_async);
 
 #ifdef GDK_WINDOWING_X11
-  window = gtk_widget_get_window (GTK_WIDGET (self->priv->parent));
+  window = gtk_widget_get_window (GTK_WIDGET (parent));
   xid = GDK_WINDOW_XID (window);
-#else
-  xid = 0;
 #endif
 
-  mime_types[0] = self->priv->content_type;
+  mime_types[0] = content_type;
   mime_types[1] = NULL;
 
-  g_dbus_proxy_call (proxy,
+  g_dbus_proxy_call (self->priv->proxy,
                      "InstallMimeTypes",
                      g_variant_new ("(u^ass)",
                                     xid,
@@ -162,34 +158,106 @@ pk_proxy_appeared_cb (GObject      *source,
 }
 
 static void
-pk_search_mime_async (GtkAppChooserOnline *obj,
-                      const gchar         *content_type,
-                      GtkWindow           *parent,
-                      GAsyncReadyCallback  callback,
-                      gpointer             user_data)
+app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
 {
-  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj);
+  iface->search_for_mimetype_async = pk_search_mime_async;
+  iface->search_for_mimetype_finish = pk_search_mime_finish;
+}
 
-  self->priv->result = g_simple_async_result_new (G_OBJECT (self),
-                                                  callback, user_data,
-                                                  gtk_app_chooser_online_search_for_mimetype_async);
-  self->priv->parent = parent;
-  self->priv->content_type = g_strdup (content_type);
-
-  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
-                            G_DBUS_PROXY_FLAGS_NONE,
-                            NULL,
-                            "org.freedesktop.PackageKit",
-                            "/org/freedesktop/PackageKit",
-                            "org.freedesktop.PackageKit.Modify",
-                            NULL,
-                            pk_proxy_appeared_cb,
-                            self);
+static void
+pk_proxy_created_cb (GObject *source,
+                     GAsyncResult *result,
+                     gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = user_data;
+  GDBusProxy *proxy;
+
+  proxy = g_dbus_proxy_new_finish (result, NULL);
+
+  if (proxy == NULL)
+    {
+      g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
+    }
+  else
+    {
+      g_simple_async_result_set_op_res_gboolean (self->priv->init_result, TRUE);
+      self->priv->proxy = proxy;
+    }
+
+  g_simple_async_result_complete (self->priv->init_result);
+  g_clear_object (&self->priv->init_result);
 }
 
 static void
-app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface)
+pk_appeared_cb (GDBusConnection *conn,
+                const gchar *name,
+                const gchar *owner,
+                gpointer user_data)
 {
-  iface->search_for_mimetype_async = pk_search_mime_async;
-  iface->search_for_mimetype_finish = pk_search_mime_finish;
+  GtkAppChooserOnlinePk *self = user_data;
+
+  /* create the proxy */
+  g_dbus_proxy_new (conn, 0, NULL,
+                    "org.freedesktop.PackageKit",
+                    "/org/freedesktop/PackageKit",
+                    "org.freedesktop.PackageKit.Modify",
+                    NULL,
+                    pk_proxy_created_cb,
+                    self);
+
+  g_bus_unwatch_name (self->priv->watch_id);
+}
+
+static void
+pk_vanished_cb (GDBusConnection *conn,
+                const gchar *name,
+                gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = user_data;
+
+  /* just return */
+  g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE);
+  g_simple_async_result_complete (self->priv->init_result);
+
+  g_bus_unwatch_name (self->priv->watch_id);
+
+  g_clear_object (&self->priv->init_result);
+}
+
+static gboolean
+app_chooser_online_pk_init_finish (GAsyncInitable *init,
+                                   GAsyncResult *res,
+                                   GError **error)
+{
+  return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res));
+}
+
+static void
+app_chooser_online_pk_init_async (GAsyncInitable *init,
+                                  int io_priority,
+                                  GCancellable *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer user_data)
+{
+  GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (init);
+
+  self->priv->init_result = g_simple_async_result_new (G_OBJECT (self),
+                                                       callback, user_data,
+                                                       gtk_app_chooser_online_get_default_async);
+
+  self->priv->watch_id =
+    g_bus_watch_name (G_BUS_TYPE_SESSION,
+                      "org.freedesktop.PackageKit",
+                      G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+                      pk_appeared_cb,
+                      pk_vanished_cb,
+                      self,
+                      NULL);
+}
+
+static void
+app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = app_chooser_online_pk_init_async;
+  iface->init_finish = app_chooser_online_pk_init_finish;
 }